﻿using Compass.Wasm.Shared.Categories;
using System.Collections.Generic;
using System.IO;
using Compass.Wasm.Shared.Extensions;
using Application = Microsoft.Office.Interop.Excel.Application;

namespace Compass.Wpf.ViewModels;

public class DrawingNumbersViewModel : NavigationViewModel
{
    #region ctor

    private readonly IDrawingNumberService _drawingNumberService;
    public ObservableRangeCollection<RadioData> Sbus { get; set; }
    public ObservableRangeCollection<RadioData> ProductTypes { get; set; }
    public ObservableRangeCollection<RadioData> ProductNames { get; set; } = new();
    public ObservableRangeCollection<RadioData> SubAssemblies { get; set; } = new();
    public DrawingNumbersViewModel(IContainerProvider provider) : base(provider)
    {
        _drawingNumberService = provider.Resolve<IDrawingNumberService>();
        //初始化
        Sbus = new ObservableRangeCollection<RadioData>
        {
            new(){Name = "FoodService" },
            new(){Name = "MEI" },
            new(){Name = "Halton" },
        };
        ProductTypes = new ObservableRangeCollection<RadioData>
        {
            new() { Name = "Normal", IsChecked = true },
            new() { Name = "Special" }
        };

        GenerateNumberCommand = new DelegateCommand(GenerateNumber);
        SbuChangeCommand = new DelegateCommand(SubChange);
        ProductNameChangeCommand = new DelegateCommand(ProductNameChange);
        SubAssemblyChangeCommand = new DelegateCommand(SubAssemblyChange);
        OpenCsvCommand = new DelegateCommand(OpenCsv);
        UpdateCommand = new DelegateCommand<string>(Update);
        SaveCommand = new DelegateCommand(Save);
        UpdateItemCommand = new DelegateCommand<DrawingNumberDto>(UpdateItem);
        DeleteItemCommand = new DelegateCommand<DrawingNumberDto>(DeleteItem);
        CurrentDto = new DrawingNumberDto();
        UpdateRoles = "admin,pm,mgr,dsr";
        BatchInputRoles = "admin";
    }
    public DelegateCommand GenerateNumberCommand { get; }
    public DelegateCommand SbuChangeCommand { get; }
    public DelegateCommand ProductNameChangeCommand { get; }
    public DelegateCommand SubAssemblyChangeCommand { get; }
    public DelegateCommand OpenCsvCommand { get; }
    public DelegateCommand<string> UpdateCommand { get; }
    public DelegateCommand SaveCommand { get; }
    public DelegateCommand<DrawingNumberDto> UpdateItemCommand { get; }
    public DelegateCommand<DrawingNumberDto> DeleteItemCommand { get; }
    #endregion

    #region 角色控制属性
    private string updateRoles;
    public string UpdateRoles
    {
        get => updateRoles;
        set { updateRoles = value; RaisePropertyChanged(); }
    }
    private string batchInputRoles;
    public string BatchInputRoles
    {
        get => batchInputRoles;
        set { batchInputRoles = value; RaisePropertyChanged(); }
    }
    #endregion

    #region 属性
    public DrawingNumberDto CurrentDto { get; set; }
    public ObservableRangeCollection<DrawingNumberDto> DrawingNumberDtos { get; set; } = new();
    private string[] drawingtypes = null!;
    public string[] DrawingTypes
    {
        get => drawingtypes;
        set { drawingtypes = value; RaisePropertyChanged(); }
    }
    #endregion

    #region 生成图号
    private void GenerateNumber()
    {
        if (!Sbus.Any(x => x.IsChecked))
        {
            Aggregator.SendMessage("请选择SBU型号");
            return;
        }
        if (!ProductNames.Any(x => x.IsChecked))
        {
            Aggregator.SendMessage("请选择产品型号");
            return;
        }
        if (!SubAssemblies.Any(x => x.IsChecked))
        {
            Aggregator.SendMessage("请选择子装配型号");
            return;
        }
        var sbu = Sbus.Single(x => x.IsChecked).Name[..1];
        var type = ProductTypes.Single(x => x.IsChecked).Name[..1];
        var product = ProductNames.Single(x => x.IsChecked).Name[..1];
        var assembly = SubAssemblies.Single(x => x.IsChecked).Name[..1];
        var number = "0001";
        if (DrawingNumberDtos.Any())
        {
            number = (DrawingNumberDtos.Select(x => Convert.ToInt32(x.Name.Substring(4))).Max()+1).ToString("0000");
        }
        CurrentDto.Id=Guid.Empty;
        CurrentDto.Name = $"{sbu}{type}{product}{assembly}{number}".ToUpper();
        CurrentDto.Description = string.Empty;
        CurrentDto.Remarks = string.Empty;
        CurrentDto.ImageUrl = string.Empty;
        CurrentDto.Type = DrawingType_e.ETO;
    }
    private void SubChange()
    {
        ProductNames.Clear();
        //取出sbus中ischecked的项目，switch，填充ProductNames
        var sbuRadio = Sbus.SingleOrDefault(x => x.IsChecked);
        if (sbuRadio is null) return;
        switch (sbuRadio.Name)
        {
            case "FoodService":
                ProductNames.Add(new() { Name = "Hood" });
                ProductNames.Add(new() { Name = "Ceiling" });
                ProductNames.Add(new() { Name = "LFU" });
                ProductNames.Add(new() { Name = "Purification" });
                ProductNames.Add(new() { Name = "ShowKitchen" });
                break;
            case "MEI":
                break;
            case "Halton":
                break;
        }
    }

    private void ProductNameChange()
    {
        SubAssemblies.Clear();
        //取出ProductNames中ischecked的项目，switch，填充SubAssemblies
        var sbuRadio = ProductNames.SingleOrDefault(x => x.IsChecked);
        if (sbuRadio is null) return;
        switch (sbuRadio.Name)
        {
            case "Hood":
                SubAssemblies.Add(new() { Name = "Exhaust" });
                SubAssemblies.Add(new() { Name = "AirSupply" });
                SubAssemblies.Add(new() { Name = "SidePanel" });
                SubAssemblies.Add(new() { Name = "MidRoof" });
                SubAssemblies.Add(new() { Name = "Bracket" });
                SubAssemblies.Add(new() { Name = "Component" });
                break;
            case "Ceiling":
                SubAssemblies.Add(new() { Name = "Exhaust" });
                SubAssemblies.Add(new() { Name = "AirSupply" });
                SubAssemblies.Add(new() { Name = "SidePanel" });
                SubAssemblies.Add(new() { Name = "MidRoof" });
                SubAssemblies.Add(new() { Name = "JetCapture" });
                SubAssemblies.Add(new() { Name = "LightBox/AlPlate" });
                SubAssemblies.Add(new() { Name = "Profile" });
                SubAssemblies.Add(new() { Name = "Bracket" });
                SubAssemblies.Add(new() { Name = "Component" });
                break;
            case "LFU":
                SubAssemblies.Add(new() { Name = "Casing" });
                SubAssemblies.Add(new() { Name = "Diffuser" });
                SubAssemblies.Add(new() { Name = "Bracket" });
                SubAssemblies.Add(new() { Name = "Component" });
                break;
            case "Purification":
                SubAssemblies.Add(new() { Name = "Frame" });
                SubAssemblies.Add(new() { Name = "SidePanel" });
                SubAssemblies.Add(new() { Name = "Bracket" });
                SubAssemblies.Add(new() { Name = "Component" });
                break;
            case "ShowKitchen":
                SubAssemblies.Add(new() { Name = "Casing" });
                SubAssemblies.Add(new() { Name = "Duct" });
                SubAssemblies.Add(new() { Name = "Bracket" });
                SubAssemblies.Add(new() { Name = "Component" });
                break;
        }
    }

    private async void SubAssemblyChange()
    {
        if (!Sbus.Any(x => x.IsChecked))
        {
            Aggregator.SendMessage("请选择SBU型号");
            return;
        }
        if (!ProductNames.Any(x => x.IsChecked))
        {
            Aggregator.SendMessage("请选择产品型号");
            return;
        }
        if (!SubAssemblies.Any(x => x.IsChecked))
        {
            Aggregator.SendMessage("请选择子装配型号");
            return;
        }
        var sbu = Sbus.Single(x => x.IsChecked).Name[..1];
        var type = ProductTypes.Single(x => x.IsChecked).Name[..1];
        var product = ProductNames.Single(x => x.IsChecked).Name[..1];
        var assembly = SubAssemblies.Single(x => x.IsChecked).Name[..1];

        var keyword = $"{sbu}{type}{product}{assembly}".ToUpper();

        var result = await _drawingNumberService.GetAllByKeywordAsync(keyword);
        if (!result.Status) return;
        DrawingNumberDtos.ReplaceRange(result.Result);
    }
    private async void Save()
    {
        if (string.IsNullOrEmpty(CurrentDto.Name))
        {
            Aggregator.SendMessage("请填写图号");
            return;
        }
        if (CurrentDto.Id==null || CurrentDto.Id == Guid.Empty)
        {
            await _drawingNumberService.AddAsync(CurrentDto);
        }
        else
        {
            await _drawingNumberService.UpdateAsync(CurrentDto.Id.Value, CurrentDto);
        }
        CurrentDto.Id=Guid.Empty;
        CurrentDto.Name = string.Empty;
        CurrentDto.Description = string.Empty;
        CurrentDto.Remarks = string.Empty;
        CurrentDto.ImageUrl = string.Empty;
        CurrentDto.Type = DrawingType_e.ETO;

        Aggregator.SendMessage("图号更新完成");
        SubAssemblyChange();
    }
    private void UpdateItem(DrawingNumberDto obj)
    {
        CurrentDto.Id = obj.Id;
        CurrentDto.Name = obj.Name;
        CurrentDto.Description = obj.Description;
        CurrentDto.Remarks = obj.Remarks;
        CurrentDto.Type = obj.Type;
        CurrentDto.ImageUrl = obj.ImageUrl;
    }
    private async void DeleteItem(DrawingNumberDto obj)
    {
        var dialogResult = await DialogHost.Question("删除确认", $"确认删除物料：{obj.Name} {obj.Description} 吗?");
        if (dialogResult.Result != ButtonResult.OK) return;
        await _drawingNumberService.DeleteAsync(obj.Id.Value);
        SubAssemblyChange();
    }
    #endregion

    #region 打开CSV文件，更新列表
    private void OpenCsv()
    {
        var path = Path.Combine(Environment.CurrentDirectory, "DrawingNumber.csv");
        var excelApp = new Application();
        excelApp.Workbooks.Open(path);
        excelApp.Visible=true;
    }

    private async void Update(string obj)
    {
        var path = Path.Combine(Environment.CurrentDirectory, "DrawingNumber.csv");
        List<DrawingNumberString> drawingNumbers;
        try
        {
            drawingNumbers= path.GetRecords<DrawingNumberString>();
        }
        //StreamReader的异常
        catch (Exception e)
        {
            Aggregator.SendMessage($"请关闭Excel后再执行更新，{e.Message}");
            return;
        }
        var dtos = (await _drawingNumberService.GetAllAsync()).Result;
        foreach (var itemDto in drawingNumbers)
        {
            //判断编号是否相同
            var dto = dtos.FirstOrDefault(x => x.Name.Equals(itemDto.Name)) ?? new DrawingNumberDto() { Id = Guid.Empty };
            dto.Name=itemDto.Name;
            dto.Description=itemDto.Description;
            dto.Remarks=itemDto.Remarks;
            dto.ImageUrl=itemDto.ImageUrl;
            dto.Type=itemDto.Type.ToEnum<DrawingType_e>();
            if (dto.Id == Guid.Empty)
            {
                await _drawingNumberService.AddAsync(dto);
            }
            else
            {
                await _drawingNumberService.UpdateAsync(dto.Id.Value, dto);
            }
        }
        Aggregator.SendMessage("更新完毕！");
        SubAssemblyChange();
    }

    #endregion

    #region 初始化
    public override void OnNavigatedTo(NavigationContext navigationContext)
    {
        base.OnNavigatedTo(navigationContext);
        DrawingTypes = Enum.GetNames(typeof(DrawingType_e));
    }
    #endregion

}

public class RadioData
{
    public string Name { get; set; }
    public bool IsChecked { get; set; }
}